#include "scanner.hh"
#include "session.hh"
#include "node.hh"
#include <QList>
#include <math.h>


dsa::Session::Session(QObject *parent)
  : QObject(parent)
  , _mainWindow(0)
  , _dummyNode(new dsa::DummyNode())
{
}



void dsa::Session::Initialize()
{
  _mainWindow = new dsa::MainWindow ();
  _mainWindow->setVisible(true);

  connect (_mainWindow->GetChartDiagram(), SIGNAL(ChangeDirectory(dsa::Node*)), this, SLOT(SetNode(dsa::Node*)));

  Scan ("/opt/programming");
}

void dsa::Session::Scan (const QString &path)
{

  dsa::Node* node = dsa::Scanner::Scan(path);
  if (!node)
    {
      return;
    }

  SetNode(node);
}


namespace
{
bool descSizeOrder (const dsa::Node* node0, const dsa::Node* node1)
{
  return (node0->GetSize() >= node1->GetSize());
}

void set_node_color (dsa::Node* node, qint64 total_size)
{
  float angle = (double)node->GetSize() * 2.0 * M_PI / (double)total_size;
  if (angle > (M_PI / 2.0f))
    {
      angle = M_PI  / 2.0f;
    }


  node->SetColor(QColor(255.0f * sin(angle), 255.0f * cos (angle), 0));

}
}

void dsa::Session::SetNode(dsa::Node *node)
{
  if (!node || node == _dummyNode)
    {
      return;
    }
  _node = node;
  qint64 absSize = _node->GetSize();
  qint64 usedSize = 0;
  QList<dsa::Node*> nodes;
  for (unsigned i=0, j=_node->GetNumberOfChildren(); i<j; ++i)
    {
      dsa::Node* nNode = _node->GetChild(i);
      if (!nNode)
        {
          continue;
        }

      qint64 nSize = nNode->GetSize();
      double fact = (double)nSize / (double)absSize;
      if (fact > 0.02)
        {
          usedSize += nNode->GetSize();
          nodes.push_back(nNode);
        }

      set_node_color (nNode, absSize);
    }
  qSort (nodes.begin(), nodes.end(), descSizeOrder);
  qint64 remain = absSize - usedSize;
  double fact = (double)remain / (double)absSize;
  if (fact >= 0.02)
    {
      _dummyNode->SetSize(remain);
      nodes.push_back(_dummyNode);
      set_node_color (_dummyNode, absSize);
    }

  _mainWindow->GetChartDiagram()->Set(_node, nodes);
  _mainWindow->GetListDiagram()->Set(_node, nodes);

}
